/*!
 * \file dmxcon/fixture.h
 * \author Christian Spoo
 * \date 03.08.2010
 *
 * \brief DMXcon fixture management
 * 
 * The fixture API provides means to create and manage the connected
 * DMX fixtures.
 */

#ifndef __LIBDMXCON__FIXTURE_H__
#define __LIBDMXCON__FIXTURE_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <dmxcon/stage.h>

/*! \defgroup FixtureChannelTypes Fixture channel types
 */
/*@{*/

enum {
  /*! \brief Mode channel */
  DMX_CHANNEL_MODE,

  /*! \brief Pan channel */
  DMX_CHANNEL_PAN,

  /*! \brief Tilt channel */
  DMX_CHANNEL_TILT,

  /*! \brief Red channel */
  DMX_CHANNEL_RED,

  /*! \brief Green channel */
  DMX_CHANNEL_GREEN,

  /*! \brief Blue channel */
  DMX_CHANNEL_BLUE,

  /*! \brief Strobe channel */
  DMX_CHANNEL_STROBE,

  /*! \brief Program channel */
  DMX_CHANNEL_PROGRAM

};
/*@}*/


enum {
  /*! \brief Big endian channel */
  DMX_CHANNEL_LITTLE_ENDIAN,

  /*! \brief Little endian channel */
  DMX_CHANNEL_BIG_ENDIAN

};


enum {
  /*! \brief Non-fading channel */
  DMX_CHANNEL_NONFADING,

  /*! \brief Fading channel */
  DMX_CHANNEL_FADING

};


/*! \brief DMX fixture channel descriptor
 */
struct fixture_channel_t {
  /*! \brief Channel type
   */
  unsigned int type;

  /*! \brief Channel offset
   */
  unsigned short offset;

  /*! \brief Channel name
   */
  char *name;

  /*! \brief Channel width
   */
  unsigned short width;

  /*! \brief Channel endianness
   */
  unsigned char endianness;

  /*! \brief Channel fade setting
   */
  unsigned char fading;

  /*! \brief Next entry in list
   */
  struct fixture_channel_t *next;
};

/*! \brief DMX fixture descriptor
 */
struct fixture_t {
  /*! \brief Pointer to the stage descriptor this device is registered in
   */
  struct stage_t *stage;

  /*! \brief Fixture name
   */
  char *name;

  /*! \brief Vendor name
   */
  char *vendor;

  /*! \brief Product name
   */
  char *product;

  /*! \brief (Virtual) start address
   */
  unsigned int start_addr;

  /*! \brief Number of occupied DMX channels
   */
  unsigned int num_channels;

  /*! \brief DMX channel value array
   */
  unsigned char *data;

  /*! \brief DMX channel descriptor list
   */
  struct fixture_channel_t *channels;
};

/*! \brief Creates a new fixture
 */
struct fixture_t *fixture_create(unsigned int start_addr, unsigned int num_channels, const char *vendor, const char *product, const char *name);

/*! \brief Destroys a fixture
 */
int fixture_destroy(struct fixture_t *fixture);

/*! \brief Adds a fixture channel
 */
struct fixture_channel_t *fixture_add_channel(struct fixture_t *fixture, unsigned short offset, unsigned int type, const char *name, unsigned short width, unsigned char endianness, unsigned char fading);

/*! \brief Removes a fixture channel
 */
int fixture_remove_channel(struct fixture_t *fixture, struct fixture_channel_t *channel);

/*! \brief Lists fixture channels
 */
int fixture_list_channels(struct fixture_t *fixture);

/*! \brief Returns channel name from channel type ID
 */
char *channel_name_from_type(unsigned int type);

/*! \brief Returns channel endianness from numerical representation
 */
char *channel_endianness_from_int(unsigned char endianness);

/*! \brief Sets fixture channel value
 */
int fixture_set_channel(struct fixture_t *fixture, unsigned int type, unsigned short index, unsigned long long value);

#ifdef __cplusplus
}
#endif

#endif

